<?php
/*微信登陆*/

namespace App\Tools;

use Ixudra\Curl\Facades\Curl;

class Wechat
{
    private $conf;
    private $appId;
    private $appSecret;
    protected $url = 'https://api.weixin.qq.com';
    
    public function __construct($pkg = '')
    {
        $this->conf = config('login');
        $key = 'wechat';
        if ($pkg == 'com.xdx.dreamcatcher') {
            $key = 'wechat_' . $pkg;
        }
        $this->appId = $this->conf[$key]['appId'];
        $this->appSecret = $this->conf[$key]['appSecret'];
    }
    
    /**
     * @desc 运行
     * @param $accessToken
     * @return mixed
     * */
    public function run($accessToken, $refreshToken, $openId)
    {
        $ret = self::getUserInfo($accessToken, $refreshToken, $openId);
        if ($ret === false) {
            return false;
        }
        return $ret;
    }
    
    /**
     * @desc 获得用户信息
     * @param @access_token
     * @return array
     * */
    private function getUserInfo($accessToken, $refreshToken, $openId)
    {
        
        if (self::getTokenStatus($accessToken, $openId) === false) {
            $refreshRet = self::refreshToken($refreshToken);
            if ($refreshRet === false) {
                return false;
            } else {
                $accessToken = $refreshRet['accessToken'];
                $openId = $refreshRet['openId'];
            }
        }
        
        $api = $this->url . "/sns/userinfo";
        $param = [
            'access_token' => $accessToken,
            'openid' => $openId
        ];
        //$result = curl_request($api, $param, 'urlencoded', 'GET');
        $result = Curl::to($api)->withData($param)->get();
        $ret = json_decode($result, true);
        
        if (isset($ret['errcode'])) {
            return false;
        }
        return [
            'unionid' => isset($ret['unionid']) ? $ret['unionid'] : '',
            'openid' => $ret['openid'],
            'nickname' => $ret['nickname'],
            'gender' => $ret['sex'],
            'province' => $ret['province'],
            'city' => $ret['city'],
            'portrait' => $ret['headimgurl']
        ];
    }
    
    /**
     * @desc 刷新token
     * @return mixed
     * */
    private function refreshToken($refreshToken)
    {
        $api = $this->url . "/sns/oauth2/refresh_token";
        $param = [
            'appid' => $this->appId,
            'grant_type' => 'refresh_token',
            'refresh_token' => $refreshToken
        ];
        //$result = curl_request($api, $param, 'urlencoded', 'GET');
        $result = Curl::to($api)->withData($param)->get();
        $ret = json_decode($result, true);
        if (isset($ret['errcode'])) {
            return false;
        }
        return ['accessToken' => $ret['access_token'], 'refreshToken' => $ret['refresh_token'], 'openId' => $ret['openid']];
    }
    
    /**
     * @desc access_token状态
     * @return bool
     * */
    private function getTokenStatus($accessToken, $openId)
    {
        $api = $this->url . "/sns/auth";
        $param = [
            'access_token' => $accessToken,
            'openid' => $openId
        ];
        //$result = curl_request($api, $param, 'urlencoded', 'GET');
        $result = Curl::to($api)->withData($param)->get();
        $ret = json_decode($result, true);
        if ($ret['errcode'] != 0) {
            return false;
        }
        return true;
    }

    /**
     * 根据code获取token
     * @return array
     * */
    public function getAccessTokenByCode($code)
    {
        //https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
        $api = $this->url . "/sns/oauth2/access_token";
        $param = [
            'appid' => $this->appId,
            'secret' => $this->appSecret,
            'code' => $code,
            'grant_type' => 'authorization_code'
        ];
        //$result = curl_request($api, $param, 'urlencoded', 'GET');
        $result = Curl::to($api)->withData($param)->get();
        $ret = json_decode($result, true);
        if (isset($ret['errcode'])) {
            return false;
        }
        return $ret;
    }


    
}